#ifndef MESSAGE_H
#define MESSAGE_H
#include "StompedReality/Base.h"
#include "StompedReality/Core.h"
#include "StompedReality/Core/Memory/DataBuffer.h"
namespace StompedReality
{
namespace Core
{
/*!
 * \author	Stefan Kazalski
 *
 * \brief	Message.
 *
 *    Messages are send between thing to communicated.<br>
 *    The message's data buffer:<br>
 *     char|unisgned|data<br>
 *     type|sender|data<br>
 */
class DLL_EXPORT Message : protected StompedReality::Core::DataBuffer
{
 private:

  int m_IterPos;
  int m_length;

 public:

  //! \brief	Constructor.
  //!   Creates an empty message. Allows iteration over data and direct access.
  //!			Total buffer size is sizeof(char) + sizeof(unsinged) + dataSize.
  //! \param	messageTye	the message type
  //! \param	parentID	the parents id
  //! \param	dataSize	size of the stored data in bytes.
  Message ( const char messageType, ID senderID, TYPE_ID senderType, int dataSize );

  //! \brief	Destructor.
  virtual ~Message( );

  //! \brief	Message type getter.
  //! \return	the message type.
  const char GetMessageType( );

  //! \brief	Message type setter.
  void ChangeMessageType ( const char messageType );

  //! \brief	Return the sender id.
  //! \return	the sender id.
  const unsigned GetSenderID( );

  //! \brief	Return the sender type.
  //! \return	the sender type.
  const unsigned GetSenderType( );

  //! \brief	Starts iteration.
  //!   Sets the iterator to the first data entry.
  void BeginIteration( );

  //! \brief Iterator More.
  bool HasMore( );

//! \brief      Iterator next
//!                     Returns the next value as T and moves to iterator in the data buffer by sizeof(T).
//! \return     next value as T
  template <class T>
  const T Next( );

  //! \brief	Generic data getter.
  //! \param	offset	the offset.
  //! \return	Data of type T.
  template <class T>
  const T GetData ( int offset )
  {
    return this->GetValue<T> ( 9 + offset );
  }

  //! \brief	Generic data setter.
  //!   Copies the data of type T into the data buffer starting at the offset.
  //! \param	offset	the offset.
  //! \param	value	the data of type T.
  template <class T>
  void SetData ( int offset, const T value )
  {
    return this->SetValue<T> ( 9 + offset, value );
  }

};

template <class T>
const T Message::Next( )
{
  const T out = this->GetValue<T> ( this->m_IterPos );
  this->m_IterPos += sizeof ( T );
  return out;
}

}
}
#endif // MESSAGE_H
